﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Security;
using System.Security.Cryptography;
using System.IO;
using System.Text;
using System.Web;

namespace RMS
{
    public static class StringExtension
    {
        [DebuggerStepThrough]
        public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
        {
            foreach (T item in enumerable)
            {
                action(item);
            }
        }
        [DebuggerStepThrough]
        public static string FormatWith(this string target, params object[] args)
        {
            return string.Format(Constants.CurrentCulture, target, args);
        }

        public static string ToVirtualPath(this string target)
        {
            return @"~/" + target.Replace(HttpContext.Current.Server.MapPath("/"), "").Replace(@"\", "/");
        }

        private static readonly byte[] CryptoSalt =
          Encoding.ASCII.GetBytes(Constants.ApplicationKey.Length.ToString(Constants.CurrentCulture));

        [DebuggerStepThrough]
        public static string Hash(this string target)
        {
            if (target != null)
            {
                using (MD5 md5 = MD5.Create())
                {
                    byte[] data = Encoding.Unicode.GetBytes(target);
                    byte[] hash = md5.ComputeHash(data);

                    return Convert.ToBase64String(hash);
                }
            }
            return null;
        }

        public static string Encrypt(this string valueToEncrypt, string key)
        {
            var rijndaelCipher = new RijndaelManaged();
            byte[] plainText = Encoding.Unicode.GetBytes(valueToEncrypt);
            var SecretKey = new PasswordDeriveBytes(key, CryptoSalt);

            using (
                ICryptoTransform encryptor = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32),
                                                                            SecretKey.GetBytes(16)))
            {
                using (var memoryStream = new MemoryStream())
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(plainText, 0, plainText.Length);
                        cryptoStream.FlushFinalBlock();
                        return Convert.ToBase64String(memoryStream.ToArray());
                    }
                }
            }
        }

        public static string Decrypt(this string valueToDecrypt, string key)
        {
            var rijndaelCipher = new RijndaelManaged();
            byte[] encryptedData = Convert.FromBase64String(valueToDecrypt);
            var secretKey = new PasswordDeriveBytes(key, CryptoSalt);

            using (
                ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32),
                                                                            secretKey.GetBytes(16)))
            {
                using (var memoryStream = new MemoryStream(encryptedData))
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        var plainText = new byte[encryptedData.Length];
                        int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
                        return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
                    }
                }
            }
        }
    }
}
